from time import sleep, time
import tkinter
import ctypes

from PIL import ImageGrab

from util.handle import get_handel


class CTkPrScrn:
    # 上次移入的窗口存留
    control_list = []
    # 上次选中的组件
    control = None
    # 当前框选区域
    current_region = []
    # 点击标记
    flag = False

    def __init__(self):
        self.__start_x, self.__start_y = 0, 0
        self.__scale = 1

        self.__win = tkinter.Tk()
        self.__win.attributes("-alpha", 0.3)  # 设置窗口半透明
        self.__win.attributes("-fullscreen", True)  # 设置全屏
        self.__win.attributes("-topmost", True)  # 设置窗口在最上层

        self.__width, self.__height = self.__win.winfo_screenwidth(), self.__win.winfo_screenheight()

        # 创建画布
        self.__canvas = tkinter.Canvas(self.__win, width=self.__width, height=self.__height, bg="gray")

        self.__win.bind('<Button-1>', self.xFunc1)  # 绑定鼠标左键点击事件
        self.__win.bind('<ButtonRelease-1>', self.xFunc1)  # 绑定鼠标左键点击释放事件
        self.__win.bind('<MouseWheel>', self.xFunc1)  # 绑定鼠标左键点击释放事件
        self.__win.bind('<B1-Motion>', self.xFunc2)  # 绑定鼠标左键点击移动事件
        self.__win.bind('<Motion>', self.motion)  # 绑定鼠标移动事件
        self.__win.bind('<Escape>', lambda e: self.__win.destroy())  # 绑定Esc按键退出事件
        self.__win.bind('<Button-3>', self.anew_motion)  # 双击重新选择根窗口

        self.__win.mainloop()  # 窗口持久化

    def xFunc1(self, event):
        print(event.type,event.state,str(event.type) == "MouseWheel")
        if event.state == 8 and str(event.type) != "MouseWheel":  # 鼠标左键按下
            self.flag =  True      # 关闭鼠标单独移动事件
            self.__start_x, self.__start_y = event.x, event.y
        elif event.state == 264 or event.state == 13 or str(event.type) == "MouseWheel":  # 鼠标左键释放
            self.flag = False        # 开启鼠标单独移动事件
            if event.x == self.__start_x or event.y == self.__start_y or self.__start_x == 0:
                # 如果鼠标是点击，则返回上一组件范围
                control_list = {
                    "parent":self.control_list[0],
                    "child":self.control
                }
            else:
                control  = {'Rect': [self.__start_x, self.__start_y,event.x, event.y]}
                control_list = {
                    "parent":None,
                    "child":control
                }

            self.__win.update()
            sleep(0.5)
            self.__win.destroy()

            # 开始截图
            ImageUtil().printscreen(control_list["child"]["Rect"],"screen.png")

            # 否则返回选中范围
            self.control = control_list



    def xFunc2(self, event):

        # print(f"鼠标左键点击了一次坐标是:x={self.__scale * event.x}, y={self.__scale * event.y}")
        if event.x == self.__start_x or event.y == self.__start_y:
            return

        Rect = [self.__start_x,self.__start_y,event.x,event.y]
        # 绘制选区
        self.draw_precinct(Rect)

    # 重新选择根窗口
    def anew_motion(self,event):
        self.control_list = []
        self.control = None
        self.hide()
        sleep(3)
        self.motion(event)

    def motion(self, event):

        if self.flag:
            return

        cursorPos = {
            "x": event.x,
            "y": event.y
        }

        # 上次查询的组件列表不为空且当前操作未跳出当前窗口
        if not (len(self.control_list) > 0 and detection().assign_in_target(cursorPos,
                                                                            self.control_list[0]["Rect"])):
            self.hide()
            self.control_list = get_handel().only_window([])
            self.show()

        self.control = detection().scope(self.control_list, cursorPos)
        # 绘制选区
        try:
            self.draw_precinct(self.control["Rect"])
        except:
            pass



    # 绘制选区
    def draw_precinct(self,Rect):
        try:
            self.__canvas.delete("prscrn")
            self.__canvas.create_rectangle(int(Rect[0]), int(Rect[1]), int(Rect[2]), int(Rect[3]),
                                           fill='blue', outline='blue', tag="prscrn")
            # 包装画布
            self.__canvas.pack()

            self.current_region = Rect
        except:
            pass

    #     窗口隐藏
    def hide(self):
        self.__win.withdraw()

    #     窗口显示
    def show(self):
        self.__win.update()
        self.__win.deiconify()


# 检查当前鼠标在哪一个组件内
class detection:
    def scope(self, control_list, cursorPos):
        # 最终查询到的组件
        control = None
        Depth = -1

        for index, item in enumerate(control_list):
            if detection().assign_in_target(cursorPos, item["Rect"]):
                if int(item["Depth"]) >= Depth:
                    control = item
                    Depth = int(item["Depth"])

        return control;

    #     判断指定坐标是否在目标坐标内
    def assign_in_target(self, assign, target):
        if assign["x"] >= int(target[0]) and assign["x"] <= int(target[2]) and assign["y"] >= int(target[1]) and assign[
            "y"] <= int(target[3]):
            return True;
        return False;

# 图像操作
class ImageUtil:
    def printscreen(self,Depth,url):
        bbox=(int(Depth[0]),int(Depth[1]),int(Depth[2]),int(Depth[3]))
        img = ImageGrab.grab(bbox)
        img.save(url)
